package com.hzw.code.security.service;

import com.google.common.collect.Lists;
import com.hzw.code.common.constant.BaseConstant;
import com.hzw.code.fast.sys.model.SysRoleModel;
import com.hzw.code.fast.sys.service.SysMenuService;
import com.hzw.code.fast.sys.service.SysRoleService;
import com.hzw.code.redis.dao.RedisDao;
import com.hzw.code.security.model.CustomUserDetails;
import com.hzw.code.fast.sys.service.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

/**
 * 自定义UserDetailsService
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {

    private final SysUserService userService;
    private final SysRoleService roleService;
    private final SysMenuService menuService;
    private final RedisDao<String,CustomUserDetails> userRedisDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 随机字符串（用于区分同一账号多次登录时，缓存的key不重复）
        String uuidKey = UUID.randomUUID().toString();
        String userTokenKey = BaseConstant.USER_KEY+username + ":" + uuidKey;
        CustomUserDetails details = userService.getUserByUsername(username);
        if(details == null){
            String errorMsg = "账号 " + username + "不存在";
            log.error(errorMsg);
            throw new UsernameNotFoundException(errorMsg);
        }
        details.setUuidKey(uuidKey);
        // 设置权限
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        List<SysRoleModel> roleList = roleService.getRoleCodeByUserId(details.getUserId());
        if(roleList == null || roleList.size() <= 0){
            details.setAuthorities(grantedAuthorities);
            userRedisDao.setKey(userTokenKey,details,null);
            return details;
        }

        // 角色
        List<String> roleStrs = Lists.newArrayList();
        for(SysRoleModel role : roleList){
            grantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleCode()));
            roleStrs.add(role.getRoleId());
        }

        // 菜单
        List<String> codeArr = menuService.getMenuByRoles(roleStrs);
        if(codeArr != null && codeArr.size() > 0){
            for (String code: codeArr) {
                grantedAuthorities.add(new SimpleGrantedAuthority(code));
            }
        }

        details.setAuthorities(grantedAuthorities);
        userRedisDao.setKey(userTokenKey,details,null);
        return details;
    }

}
